namespace WeatherSystem.API.CQRS
{
    /// <summary>
    /// 中介者模式实现
    /// </summary>
    public class Mediator : IMediator
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ILogger<Mediator> _logger;

        public Mediator(IServiceProvider serviceProvider, ILogger<Mediator> logger)
        {
            _serviceProvider = serviceProvider;
            _logger = logger;
        }

        public async Task SendAsync(ICommand command)
        {
            var commandType = command.GetType();
            var handlerType = typeof(ICommandHandler<>).MakeGenericType(commandType);
            
            var handler = _serviceProvider.GetService(handlerType);
            if (handler == null)
            {
                throw new InvalidOperationException($"未找到命令处理器: {commandType.Name}");
            }

            var method = handlerType.GetMethod("HandleAsync");
            if (method == null)
            {
                throw new InvalidOperationException($"处理器缺少HandleAsync方法: {handlerType.Name}");
            }

            try
            {
                var task = (Task)method.Invoke(handler, new object[] { command })!;
                await task;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "执行命令失败: {CommandType}", commandType.Name);
                throw;
            }
        }

        public async Task<TResult> SendAsync<TResult>(ICommand<TResult> command)
        {
            var commandType = command.GetType();
            var handlerType = typeof(ICommandHandler<,>).MakeGenericType(commandType, typeof(TResult));
            
            var handler = _serviceProvider.GetService(handlerType);
            if (handler == null)
            {
                throw new InvalidOperationException($"未找到命令处理器: {commandType.Name}");
            }

            var method = handlerType.GetMethod("HandleAsync");
            if (method == null)
            {
                throw new InvalidOperationException($"处理器缺少HandleAsync方法: {handlerType.Name}");
            }

            try
            {
                var task = (Task<TResult>)method.Invoke(handler, new object[] { command })!;
                return await task;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "执行命令失败: {CommandType}", commandType.Name);
                throw;
            }
        }

        public async Task<TResult> QueryAsync<TResult>(IQuery<TResult> query)
        {
            var queryType = query.GetType();
            var handlerType = typeof(IQueryHandler<,>).MakeGenericType(queryType, typeof(TResult));
            
            var handler = _serviceProvider.GetService(handlerType);
            if (handler == null)
            {
                throw new InvalidOperationException($"未找到查询处理器: {queryType.Name}");
            }

            var method = handlerType.GetMethod("HandleAsync");
            if (method == null)
            {
                throw new InvalidOperationException($"处理器缺少HandleAsync方法: {handlerType.Name}");
            }

            try
            {
                var task = (Task<TResult>)method.Invoke(handler, new object[] { query })!;
                return await task;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "执行查询失败: {QueryType}", queryType.Name);
                throw;
            }
        }
    }
}